library Item requires Table, Itemdex, Dto

    /*
    --------------------------------------------------------------------------
    # Item
    --------------------------------------------------------------------------
    * param 
    */
    struct Item extends array
        item m_item

        delegate ItemType m_itemType

        static method get takes item it returns thistype
            local thistype this = thistype(GetItemId(it))
            if this.m_item != null and this.m_item == it then
                return this
            endif

            debug call BJDebugMsg("Item.create: " + I2S(this) + GetItemName(it))
            
            set this.m_item = it
            set this.m_itemType = ItemType.create(GetItemTypeId(it))
            
            return this
        endmethod

        method isNull takes nothing returns boolean
            return (GetItemTypeId(this.m_item) == 0) or (GetWidgetLife(this.m_item) < 1.0)
        endmethod

        method destroy takes nothing returns nothing
            set this.m_item = null
        endmethod

    endstruct

    /*
    --------------------------------------------------------------------------
    # 延迟给与物品
    --------------------------------------------------------------------------
    * param 
    */
    private function anon_8e8ad269 takes nothing returns nothing
        local Dto dto = GetTimerData(GetExpiredTimer())
        set bj_lastCreatedItem = CreateItem(dto.m_data, GetUnitX(dto.m_unit), GetUnitY(dto.m_unit))
        call UnitAddItem(dto.m_unit, bj_lastCreatedItem)
        call UnitDropItemSlot(dto.m_unit, bj_lastCreatedItem, dto.m_int)
        set bj_lastCreatedItem = null
        call dto.destroy()
    endfunction

    function DelayAddItem takes unit u, integer itemType, integer slot, real timeout returns nothing
        local Dto dto = Dto.create()
        set dto.m_unit = u
        set dto.m_data = itemType
        set dto.m_int = slot
        call TimerStart(dto.getTimer(), timeout, false, function anon_8e8ad269)
    endfunction
    /*
    --------------------------------------------------------------------------
    # 根据物品类型获取背包索引
    --------------------------------------------------------------------------
    * param 
    */
    function GetInventoryIndexByItemType takes unit whichUnit, integer itemType returns integer
        local item oItem
        local integer index
        set index = 0
        loop
            exitwhen index >= bj_MAX_INVENTORY
            set oItem = UnitItemInSlot(whichUnit, index)
            if (oItem != null) and (GetItemTypeId(oItem) == itemType) then
                set oItem = null
                return index
            endif
            set index = index + 1
        endloop
        set oItem = null
        return - 1
    endfunction
    /*
    --------------------------------------------------------------------------
    # 获取同样类型的物品
    --------------------------------------------------------------------------
    * param 
    */
    function GetTheSameItemInSlot takes unit whichUnit, item it returns item
        local item oItem
        local integer index

        set index = 0
        loop
            exitwhen index >= bj_MAX_INVENTORY
            set oItem = UnitItemInSlot(whichUnit, index)
            if (oItem != null) and (oItem != it) and (GetItemTypeId(oItem) == GetItemTypeId(it)) then
                return oItem
            endif
            set index = index + 1
        endloop
        set oItem = null
        return oItem
    endfunction
    /*
    --------------------------------------------------------------------------
    # 合并单位背包中同样类型的物品（有数量的）
    --------------------------------------------------------------------------
    * param 
    */
    function MergeTheSameItemInSlot takes unit whichUnit, item it returns nothing
        local item myit = GetTheSameItemInSlot(whichUnit, it)
        local integer chargesA
        local integer chargesB

        // 存在相同类型的(有数量的)物品就叠加数量
        if myit != null then
            set chargesA = GetItemCharges(myit)
            set chargesB = GetItemCharges(it)

            debug call BJDebugMsg("mergeTheSameItemInUnitSlot:charges " + I2S(chargesA) + "|" + I2S(chargesB))

            if chargesA > 0 and chargesB > 0 then
                call SetItemCharges(myit, chargesA + chargesB)
                call RemoveItem(it)
            endif
        endif
        set myit = null
    endfunction

    //--------------------------------------------------------------------------
    // 初始化物品
    private function PickupItem takes unit u, item it returns nothing
        if GetItemTypeId(it) == XE_DUMMY_ITEMID then
            return
        endif
        if GetItemType(it) != ITEM_TYPE_POWERUP then
            // 叠加相同的物品
            call MergeTheSameItemInSlot(u, it)
        endif
    endfunction

    //丢弃物品
    private function DropItem takes unit u, item it returns nothing
    endfunction

    //使用物品
    private function UseItem takes unit u, item it returns nothing
    endfunction

    //典当物品
    private function PawnItem takes unit u, item it returns nothing
    endfunction

    private function Init takes nothing returns nothing
        //单位拾起物品
        call RegisterPickupItemResponse(PickupItem)
        //单位丢弃物品
        call RegisterDropItemResponse(DropItem)
        //单位使用物品
        call RegisterUseItemResponse(UseItem)
        //单位典当物品
        call RegisterPawnItemResponse(PawnItem)
    endfunction

    type ItemList extends Item array [18]

endlibrary